using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 有限状态机
/// </summary>
public class StateMachine
{
    private Dictionary<string, IState> _states;
    private IState _currentState;
    private IState _previousState;

    public StateMachine()
    {
        _states = new Dictionary<string, IState>();
    }

    /// <summary>
    /// 添加状态
    /// </summary>
    /// <param name="name">状态名称</param>
    /// <param name="state">状态实例</param>
    public void AddState(string name, IState state)
    {
        if (!_states.ContainsKey(name))
        {
            _states.Add(name, state);
        }
        else
        {
            Debug.LogWarning("状态机中已存在名为 " + name + " 的状态");
        }
    }

    /// <summary>
    /// 切换状态
    /// </summary>
    /// <param name="name">要切换到的状态名称</param>
    public void ChangeState(string name)
    {
        if (!_states.ContainsKey(name))
        {
            Debug.LogError("状态机中不存在名为 " + name + " 的状态");
            return;
        }

        // 退出当前状态
        if (_currentState != null)
        {
            _currentState.OnExit();
        }

        // 记录前一个状态
        _previousState = _currentState;

        // 切换到新状态
        _currentState = _states[name];
        _currentState.OnEnter();
    }

    /// <summary>
    /// 更新状态机
    /// </summary>
    public void Update()
    {
        if (_currentState != null)
        {
            _currentState.OnUpdate();
        }
    }

    /// <summary>
    /// 获取当前状态
    /// </summary>
    /// <returns>当前状态</returns>
    public IState GetCurrentState()
    {
        return _currentState;
    }

    /// <summary>
    /// 获取前一个状态
    /// </summary>
    /// <returns>前一个状态</returns>
    public IState GetPreviousState()
    {
        return _previousState;
    }

    /// <summary>
    /// 返回到前一个状态
    /// </summary>
    public void RevertToPreviousState()
    {
        if (_previousState != null)
        {
            // 退出当前状态
            if (_currentState != null)
            {
                _currentState.OnExit();
            }

            // 切换回前一个状态
            IState temp = _currentState;
            _currentState = _previousState;
            _previousState = temp;
            _currentState.OnEnter();
        }
    }
}